//时间相关
import moment from 'moment'; // 时间过滤器
/**
 * 判断两个日期之间的间隔是否超过一个月
 * @param date1 起始时间
 * @param date2 结束时间
 * @returns boolean 是否超过一个月
 */
export const isBeyondOneMonth = (date1: Date | string, date2: Date | string, monthNum: number = 1): boolean => {
  const _date1 = moment(date1);
  const _date2 = moment(date2);
  const diffInMonths = _date2.diff(_date1, 'months', true); // 浮点数月份差
  return Math.abs(diffInMonths) > monthNum;
};

/**
 * 获取当前时间格式化字符串（年月日时拼接）
 * 示例：2025070108
 */
export const formatCurrentTime = (): string => {
  const date = new Date();
  const Y = date.getFullYear();
  const M = (date.getMonth() + 1).toString().padStart(2, '0');
  const D = date.getDate().toString().padStart(2, '0');
  const H = date.getHours().toString();
  return `${Y}${M}${D}${H}`;
};

/**
 * 格式化时间为指定格式，默认为 YYYY-MM-DD
 * @param value 时间对象或字符串
 * @param formatString 输出格式
 */
export const formatDate = (value: Date | string = new Date(), formatString: string = 'YYYY-MM-DD'): string => {
  if (!value) return '--';
  return moment(value).format(formatString);
};
//转换时间
export const time = (value: Date | string = new Date(), formatString: string = 'YYYY-MM-DD HH:mm:ss') => {
  return formatDate(value, formatString);
};
//转换时间
export const day = (value: Date | string = new Date(), formatString: string = 'YYYY-MM-DD') => {
  return formatDate(value, formatString);
};
/**
 * 比较两个时间的先后关系
 * @param startTime 开始时间
 * @param endTime 结束时间
 * @returns -1 表示开始时间早于结束时间；1 表示晚于；0 表示相同
 */
export const compareDates = (startTime: Date | string, endTime: Date | string): -1 | 0 | 1 => {
  if (!startTime || !endTime) {
    return 0;
  }
  const date1 = new Date(startTime);
  const date2 = new Date(endTime);

  if (isNaN(date1.getTime()) || isNaN(date2.getTime())) {
    throw new Error('时间格式不正确');
  }

  if (date1 < date2) return -1;
  else if (date1 > date2) return 1;
  else return 0;
};

/**
 * 获取两个时间之间的分钟差
 * @param startTime 开始时间
 * @param endTime 结束时间
 * @returns number 分钟差值
 */
export const getMinutesDifference = (startTime: Date | string, endTime: Date | string): number => {
  if (!startTime || !endTime) {
    return 0;
  }

  const start = new Date(startTime);
  const end = new Date(endTime);

  if (isNaN(start.getTime()) || isNaN(end.getTime())) {
    throw new Error('时间格式不正确');
  }

  const diffMs = end.getTime() - start.getTime();
  return Math.floor(diffMs / (1000 * 60));
};

/**
 * 获取某个时间段前的日期
 * @param value 时间跨度数量
 * @param unit 单位 day|week|month|year
 * @param baseDate 基准时间
 * @param formatString 输出格式
 */
export const getTimeAgo = (
  value: number,
  unit: 'day' | 'days' | 'weeks' | 'week' | 'months' | 'month' | 'year' | 'years' = 'day',
  baseDate: Date | string = new Date(),
  formatString: string = 'YYYY-MM-DD',
): string => {
  switch (unit) {
    case 'day':
    case 'days':
      return moment(baseDate).subtract(value, 'days').format(formatString);
    case 'week':
    case 'weeks':
      return moment(baseDate).subtract(value, 'weeks').startOf('isoWeek').format(formatString);
    case 'month':
    case 'months':
      return moment(baseDate).subtract(value, 'months').format(formatString);
    case 'year':
    case 'years':
      return moment(baseDate).subtract(value, 'years').format(formatString);
    default:
      return '--';
  }
};
/**
 * 获取某一天是星期几
 * @param value 时间对象或字符串
 * @returns 星期名称（如：星期一）
 */
export const getDayName = (value: Date | string = new Date()): string => {
  const days = ['星期天', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
  return days[new Date(value).getDay()];
};
/**
 * 获取相对时间描述
 * @param value 时间对象或字符串
 * @returns 如 "3小时前"
 */
export const getRelativeTime = (value: Date | string): string => {
  return moment(value).fromNow();
};

/**
 * 获取某个时间加上若干分钟后的新时间
 * @param date 基准时间
 * @param minutes 增加的分钟数
 * @param formatString 输出格式
 */
export const addMinutesToTime = (date: Date | string, minutes: number, formatString: string = 'YYYY-MM-DD HH:mm:ss'): string => {
  return moment(date).add(minutes, 'minutes').format(formatString);
};

/**
 * 计算与目标日期相差的天数
 * @param inputDate 目标日期
 * @param today 当前日期
 * @returns { dayDiff: number, dayDiffText: string } 差异天数及描述
 */
export const getDaysUntilDeadline = (inputDate: Date | string, today: Date = new Date()): { dayDiff: number; dayDiffText: string } => {
  let date: Date;

  if (!inputDate) {
    return {
      dayDiff: 0,
      dayDiffText: '未知',
    };
  }
  today = new Date(today);
  if (typeof inputDate === 'string') {
    date = new Date(inputDate);
  } else if (inputDate instanceof Date) {
    date = new Date(inputDate);
  } else {
    throw new Error('inputDate 必须是 Date 对象或有效的日期字符串');
  }
  // 获取今天的日期，不包含当前时间（即设为00:00:00）
  today.setHours(0, 0, 0, 0);
  date.setHours(0, 0, 0, 0);

  const timeDiff = date.getTime() - today.getTime();
  const dayDiff = Math.round(timeDiff / (1000 * 3600 * 24));
  const dayDiffText = dayDiff >= 0 ? `还剩 ${dayDiff} 天` : `超期 ${-dayDiff} 天`;

  return { dayDiff, dayDiffText };
};

/**
 * 获取两个日期之间的年份差
 * @param startDate 起始日期
 * @param endDate 结束日期（默认为今天）
 * @returns 年龄或年份差
 */
export const getYearDifference = (startDate: Date | string, endDate: Date | string = new Date()): number => {
  const start = new Date(startDate);
  const end = new Date(endDate);

  let yearDiff = end.getFullYear() - start.getFullYear();

  const monthDiff = end.getMonth() - start.getMonth();
  if (monthDiff < 0 || (monthDiff === 0 && end.getDate() < start.getDate())) {
    yearDiff--;
  }

  return yearDiff;
};
